package de.bloxel.ui;

import com.jme3.collision.CollisionResult;
import com.jme3.input.controls.ActionListener;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;

import de.bloxel.controller.UIEvent;
import de.bloxel.core.BloxelFactory;
import de.bloxel.core.BloxelFactory.BloxelType;
import de.bloxel.core.LoadEvent;
import de.bloxel.core.SaveEvent;
import de.bloxel.core.events.Event;
import de.bloxel.core.water.WaterEvent;
import de.bloxel.world.TerrainChunk;

/**
 * @author hauschild
 * @author andreas.hoehmann@gmx.de
 * 
 * @since 0.0.0
 */
public class BloxelActionController implements ActionListener {

  public static class MoveEvent extends Event {

    public final boolean left;
    public final boolean right;
    public final boolean forward;
    public final boolean backward;

    public MoveEvent(final boolean moveLeft, final boolean moveRight, final boolean moveForward,
        final boolean moveBackward) {
      super("Move");
      left = moveLeft;
      right = moveRight;
      forward = moveForward;
      backward = moveBackward;
    }

  }

  public static final String SAVE_ACTION = "Save";
  public static final String LOAD_ACTION = "Load";
  public static final String ATTACH_ACTION = "Shoot";
  public static final String DETACH_ACTION = "Detach";
  public static final String MENU_ACTION = "Exit";
  private boolean left = false, right = false, up = false, down = false;
  private final BloxelApplication bloxelApplication;
  private final TerrainChunk terrainChunk;
  private final BloxelInventory bloxelInventory;

  public BloxelActionController(final BloxelApplication theBloxelApplication, final TerrainChunk theTerrainChunk,
      final BloxelInventory theBloxelInventory) {
    bloxelApplication = theBloxelApplication;
    terrainChunk = theTerrainChunk;
    bloxelInventory = theBloxelInventory;
  }

  private void actionAddBloxel() {
    final CollisionResult cr = bloxelApplication.checkTargetPosition();
    if (cr != null) {
      if (cr.getGeometry() != null) {
        final Vector3f targetPosition = new Vector3f(cr.getGeometry().getWorldBound().getCenter()
            .add(cr.getContactNormal().mult(BloxelFactory.DEFAULT_BLOXEL_DIMENSION * 2)));
        final BloxelType selectedBoxelType = bloxelInventory.getSelectedBoxelType();
        terrainChunk.addTerrainElement(targetPosition, selectedBoxelType);
        if (selectedBoxelType == BloxelType.WATER) {
          bloxelApplication.eventManager.queueEvent(new WaterEvent("waterSourceCreate", targetPosition, FastMath
              .nextRandomInt(10, 20)));
        }
        bloxelApplication.updateTerrain();
      } else {
        // we hit the terrain node
        final Vector3f targetPosition = new Vector3f(cr.getContactPoint());
        System.out.println(targetPosition);
        final BloxelType selectedBoxelType = bloxelInventory.getSelectedBoxelType();
        terrainChunk.addTerrainElement(targetPosition, selectedBoxelType);
        bloxelApplication.updateTerrain();
      }
    }
  }

  private void actionRemoveBloxel() {
    final CollisionResult cr = bloxelApplication.checkTargetPosition();
    if (cr != null) {
      if (cr.getGeometry() != null) {
        final Vector3f targetPosition = cr.getGeometry().getWorldBound().getCenter();
        terrainChunk.removeTerrainElement(targetPosition);
        bloxelApplication.updateTerrain();
      }
    }
  }

  public TerrainChunk getTerrainChunk() {
    return terrainChunk;
  }

  public boolean isDown() {
    return down;
  }

  public boolean isLeft() {
    return left;
  }

  public boolean isRight() {
    return right;
  }

  public boolean isUp() {
    return up;
  }

  @Override
  public void onAction(final String name, final boolean isPressed, final float tpf) {
    if (name.equals("Lefts")) {
      left = isPressed;
    } else if (name.equals("Rights")) {
      right = isPressed;
    } else if (name.equals("Ups")) {
      up = isPressed;
    } else if (name.equals("Downs")) {
      down = isPressed;
    } else if (name.equals("Jumps")) {
      bloxelApplication.getPlayer().jump();
    }
    if (name.equals(SAVE_ACTION) && !isPressed) {
      bloxelApplication.eventManager.queueEvent(new SaveEvent("scene.save"));
    }
    if (name.equals(LOAD_ACTION) && !isPressed) {
      bloxelApplication.eventManager.queueEvent(new LoadEvent("scene.save"));
    }
    if (name.equals(MENU_ACTION) && !isPressed) {
      // bloxelApplication.getNiftyDisplay().getNifty().gotoScreen("menu");
      bloxelApplication.eventManager.queueEvent(new UIEvent(UIEvent.Action.ToggleMenu));
    }
    if (name.equals(DETACH_ACTION) && !isPressed) {
      actionRemoveBloxel();
    }
    if (name.equals(ATTACH_ACTION) && !isPressed) {
      actionAddBloxel();
    }
  }
}
